home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / amiutils / i_l / irit5 / triv_lib / trivcmpt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-31  |  9.1 KB  |  257 lines

  1. /******************************************************************************
  2. * TrivCmpt.c - Make objects compatible.                          *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Sep. 91.                          *
  5. ******************************************************************************/
  6.  
  7. #include "triv_loc.h"
  8.  
  9. /*****************************************************************************
  10. * DESCRIPTION:                                                               M
  11. * Given two trivariates, makes them compatible by:                 M
  12. * 1. Coercing their point type to be the same.                     M
  13. * 2. Making them have the same curve type.                     M
  14. * 3. Raising the degree of the lower one to be the same as the higher.         M
  15. * 4. Refining them to a common knot vector (If Bspline and SameOrder).         M
  16. *                                                                            M
  17. * Note 3 is performed if SameOrder TRUE, 4 if SameKV TRUE.             M
  18. * Both trivariates are modified IN PLACE.                     M
  19. *                                                                            *
  20. * PARAMETERS:                                                                M
  21. *   TV1, TV2:  Two surfaces to be made compatible, in place.                 M
  22. *   SameUOrder:  If TRUE, this routine make sure they share the same U       M
  23. *                order.                                 M
  24. *   SameVOrder:  If TRUE, this routine make sure they share the same V       M
  25. *                order.                                 M
  26. *   SameWOrder:  If TRUE, this routine make sure they share the same W       M
  27. *                order.                                 M
  28. *   SameUKV:     If TRUE, this routine make sure they share the same U       M
  29. *                knot vector and hence continuity.                           *
  30. *   SameVKV:     If TRUE, this routine make sure they share the same V       M
  31. *                knot vector and hence continuity.                           M
  32. *   SameWKV:     If TRUE, this routine make sure they share the same W       M
  33. *                knot vector and hence continuity.                           M
  34. *                                                                            *
  35. * RETURN VALUE:                                                              M
  36. *   CagdBType:   TRUE if successful, FALSE otherwise.                        M
  37. *                                                                            *
  38. * KEYWORDS:                                                                  M
  39. *   TrivMakeTVsCompatible, compatibility                                     M
  40. *****************************************************************************/
  41. CagdBType TrivMakeTVsCompatible(TrivTVStruct **TV1,
  42.                 TrivTVStruct **TV2,
  43.                 CagdBType SameUOrder,
  44.                 CagdBType SameVOrder,
  45.                 CagdBType SameWOrder,
  46.                 CagdBType SameUKV,
  47.                 CagdBType SameVKV,
  48.                 CagdBType SameWKV)
  49. {
  50.     int i, KV1Len, KV2Len, RefLen;
  51.     CagdRType *KV1, *KV2, *RefKV;
  52.     TrivTVStruct *TmpTV;
  53.     CagdPointType CommonPType;
  54.  
  55.     if ((*TV1 == NULL) || (*TV2 == NULL))
  56.     return TRUE;
  57.  
  58.     CommonPType = CagdMergePointType((*TV1) -> PType, (*TV2) -> PType);
  59.  
  60.     /* Make the point types compatible. */
  61.     if (CommonPType != (*TV1) -> PType) {
  62.     TmpTV = TrivCoerceTVTo(*TV1, CommonPType);
  63.     TrivTVFree(*TV1);
  64.     *TV1 = TmpTV;
  65.     }
  66.     if (CommonPType != (*TV2) -> PType) {
  67.     TmpTV = TrivCoerceTVTo(*TV2, CommonPType);
  68.     TrivTVFree(*TV2);
  69.     *TV2 = TmpTV;
  70.     }
  71.  
  72.     if (SameUOrder) {
  73.     /* Raise the degree of the lower one. */
  74.     for (i = (*TV1) -> UOrder; i < (*TV2) -> UOrder; i++) {
  75.         TmpTV = TrivTVDegreeRaise(*TV1, TRIV_CONST_U_DIR);
  76.         TrivTVFree(*TV1);
  77.         *TV1 = TmpTV;
  78.     }
  79.     for (i = (*TV2) -> UOrder; i < (*TV1) -> UOrder; i++) {
  80.         TmpTV = TrivTVDegreeRaise(*TV2, TRIV_CONST_U_DIR);
  81.         TrivTVFree(*TV2);
  82.         *TV2 = TmpTV;
  83.     }
  84.     }
  85.     if (SameVOrder) {
  86.     for (i = (*TV1) -> VOrder; i < (*TV2) -> VOrder; i++) {
  87.         TmpTV = TrivTVDegreeRaise(*TV1, TRIV_CONST_V_DIR);
  88.         TrivTVFree(*TV1);
  89.         *TV1 = TmpTV;
  90.     }
  91.     for (i = (*TV2) -> VOrder; i < (*TV1) -> VOrder; i++) {
  92.         TmpTV = TrivTVDegreeRaise(*TV2, TRIV_CONST_V_DIR);
  93.         TrivTVFree(*TV2);
  94.         *TV2 = TmpTV;
  95.     }
  96.     }
  97.     if (SameWOrder) {
  98.     for (i = (*TV1) -> WOrder; i < (*TV2) -> WOrder; i++) {
  99.         TmpTV = TrivTVDegreeRaise(*TV1, TRIV_CONST_W_DIR);
  100.         TrivTVFree(*TV1);
  101.         *TV1 = TmpTV;
  102.     }
  103.     for (i = (*TV2) -> WOrder; i < (*TV1) -> WOrder; i++) {
  104.         TmpTV = TrivTVDegreeRaise(*TV2, TRIV_CONST_W_DIR);
  105.         TrivTVFree(*TV2);
  106.         *TV2 = TmpTV;
  107.     }
  108.     }
  109.  
  110.     /* If incompatible surface type - make it the same as well. */
  111.     if ((*TV1) -> GType != (*TV2) -> GType) {
  112.     /* Assume both surfaces are either Bezier or Bspline surfaces. */
  113.     if ((*TV1) -> GType != (*TV2) -> GType) {
  114.         /* If Bezier basis - promote to bspline: */
  115.         if ((*TV1) -> GType == TRIV_TVBEZIER_TYPE) {
  116.         TmpTV = TrivCnvrtBezier2BsplineTV(*TV1);
  117.         TrivTVFree(*TV1);
  118.         *TV1 = TmpTV;
  119.         }
  120.         if ((*TV2) -> GType == TRIV_TVBEZIER_TYPE) {
  121.         TmpTV = TrivCnvrtBezier2BsplineTV(*TV2);
  122.         TrivTVFree(*TV2);
  123.         *TV2 = TmpTV;
  124.         }
  125.     }
  126.     }
  127.  
  128.     if ((*TV1) -> GType == TRIV_TVBSPLINE_TYPE) {
  129.     /* If bspline surface - make sure knot vectors are the same. */
  130.  
  131.     if (SameUKV && SameUOrder) {
  132.         /* Handle the U Direction. */
  133.         int Order = (*TV1) -> UOrder;
  134.  
  135.         KV1 = (*TV1) -> UKnotVector;
  136.         KV2 = (*TV2) -> UKnotVector;
  137.         KV1Len = (*TV1) -> ULength + Order;
  138.         KV2Len = (*TV2) -> ULength + Order;
  139.  
  140.         /* Affine map second knot vector to span same parametric domain. */
  141.         BspKnotAffineTrans(KV2, KV2Len, KV1[Order - 1] - KV2[Order - 1],
  142.                    (KV1[KV1Len - Order] - KV1[Order - 1]) /
  143.                    (KV2[KV2Len - Order] - KV2[Order - 1]));
  144.  
  145.         /* Find knots in KV2 which are not in KV1 and refine TV1 there. */
  146.         RefKV  = BspKnotSubtrTwo(&KV2[Order - 1], KV2Len - Order * 2 + 2,
  147.                      &KV1[Order - 1], KV1Len - Order * 2 + 2,
  148.                      &RefLen);
  149.         if (RefLen > 0) {
  150.         TmpTV = TrivTVRefineAtParams(*TV1, TRIV_CONST_U_DIR,
  151.                          FALSE, RefKV, RefLen);
  152.         TrivTVFree(*TV1);
  153.         *TV1 = TmpTV;
  154.         KV1 = (*TV1) -> UKnotVector;
  155.         KV1Len = (*TV1) -> ULength + Order;
  156.         }
  157.         IritFree((VoidPtr) RefKV);
  158.  
  159.         /* Find knots in KV1 which are not in KV2 and refine TV2 there. */
  160.         RefKV  = BspKnotSubtrTwo(&KV1[Order - 1], KV1Len - Order * 2 + 2,
  161.                      &KV2[Order - 1], KV2Len - Order * 2 + 2,
  162.                      &RefLen);
  163.         if (RefLen > 0) {
  164.         TmpTV = TrivTVRefineAtParams(*TV2, TRIV_CONST_U_DIR,
  165.                          FALSE, RefKV, RefLen);
  166.         TrivTVFree(*TV2);
  167.         *TV2 = TmpTV;
  168.         }
  169.         IritFree((VoidPtr) RefKV);
  170.     }
  171.  
  172.     if (SameVKV && SameVOrder) {
  173.         /* Handle the V Direction. */
  174.         int Order = (*TV1) -> VOrder;
  175.  
  176.         KV1 = (*TV1) -> VKnotVector;
  177.         KV2 = (*TV2) -> VKnotVector;
  178.         KV1Len = (*TV1) -> VLength + Order;
  179.         KV2Len = (*TV2) -> VLength + Order;
  180.  
  181.         /* Affine map second knot vector to span same parametric domain. */
  182.         BspKnotAffineTrans(KV2, KV2Len, KV1[Order - 1] - KV2[Order - 1],
  183.                    (KV1[KV1Len - Order] - KV1[Order - 1]) /
  184.                    (KV2[KV2Len - Order] - KV2[Order - 1]));
  185.  
  186.         /* Find knots in KV2 which are not in KV1 and refine TV1 there. */
  187.         RefKV  = BspKnotSubtrTwo(&KV2[Order - 1], KV2Len - Order * 2 + 2,
  188.                      &KV1[Order - 1], KV1Len - Order * 2 + 2,
  189.                      &RefLen);
  190.         if (RefLen > 0) {
  191.         TmpTV = TrivTVRefineAtParams(*TV1, TRIV_CONST_V_DIR,
  192.                          FALSE, RefKV, RefLen);
  193.         TrivTVFree(*TV1);
  194.         *TV1 = TmpTV;
  195.         KV1 = (*TV1) -> VKnotVector;
  196.         KV1Len = (*TV1) -> VLength + Order;
  197.         }
  198.         IritFree((VoidPtr) RefKV);
  199.  
  200.         /* Find knots in KV1 which are not in KV2 and refine TV2 there. */
  201.         RefKV = BspKnotSubtrTwo(&KV1[Order - 1], KV1Len - Order * 2 + 2,
  202.                     &KV2[Order - 1], KV2Len - Order * 2 + 2,
  203.                     &RefLen);
  204.         if (RefLen > 0) {
  205.         TmpTV = TrivTVRefineAtParams(*TV2, TRIV_CONST_V_DIR,
  206.                          FALSE, RefKV, RefLen);
  207.         TrivTVFree(*TV2);
  208.         *TV2 = TmpTV;
  209.         }
  210.         IritFree((VoidPtr) RefKV);
  211.     }
  212.  
  213.     if (SameWKV && SameWOrder) {
  214.         /* Handle the V Direction. */
  215.         int Order = (*TV1) -> WOrder;
  216.  
  217.         KV1 = (*TV1) -> WKnotVector;
  218.         KV2 = (*TV2) -> WKnotVector;
  219.         KV1Len = (*TV1) -> WLength + Order;
  220.         KV2Len = (*TV2) -> WLength + Order;
  221.  
  222.         /* Affine map second knot vector to span same parametric domain. */
  223.         BspKnotAffineTrans(KV2, KV2Len, KV1[Order - 1] - KV2[Order - 1],
  224.                    (KV1[KV1Len - Order] - KV1[Order - 1]) /
  225.                    (KV2[KV2Len - Order] - KV2[Order - 1]));
  226.  
  227.         /* Find knots in KV2 which are not in KV1 and refine TV1 there. */
  228.         RefKV = BspKnotSubtrTwo(&KV2[Order - 1], KV2Len - Order * 2 + 2,
  229.                     &KV1[Order - 1], KV1Len - Order * 2 + 2,
  230.                     &RefLen);
  231.         if (RefLen > 0) {
  232.         TmpTV = TrivTVRefineAtParams(*TV1, TRIV_CONST_W_DIR,
  233.                          FALSE, RefKV, RefLen);
  234.         TrivTVFree(*TV1);
  235.         *TV1 = TmpTV;
  236.         KV1 = (*TV1) -> WKnotVector;
  237.         KV1Len = (*TV1) -> WLength + Order;
  238.         }
  239.         IritFree((VoidPtr) RefKV);
  240.  
  241.         /* Find knots in KV1 which are not in KV2 and refine TV2 there. */
  242.         RefKV  = BspKnotSubtrTwo(&KV1[Order - 1], KV1Len - Order * 2 + 2,
  243.                      &KV2[Order - 1], KV2Len - Order * 2 + 2,
  244.                      &RefLen);
  245.         if (RefLen > 0) {
  246.         TmpTV = TrivTVRefineAtParams(*TV2, TRIV_CONST_W_DIR,
  247.                          FALSE, RefKV, RefLen);
  248.         TrivTVFree(*TV2);
  249.         *TV2 = TmpTV;
  250.         }
  251.         IritFree((VoidPtr) RefKV);
  252.     }
  253.     }
  254.  
  255.     return TRUE;
  256. }
  257.